From 1eb531338f5ae3696fa9d68a4171a73f0107c2f8 Mon Sep 17 00:00:00 2001 From: Factiven Date: Fri, 4 Aug 2023 14:49:35 +0700 Subject: Update v3.8.5 - Merged Beta to Main (#32) * initial commit * Update_v.3.6.7-beta-v1.2 * Update_v.3.6.7-beta-v1.3 * Update_v.3.6.7-beta-v1.3 > update API * Fixed mediaList won't update * added .env disqus shortname * Update_v3.6.7-beta-v1.4 >Implementing database * Create main.yml * Update v3.6.7-beta-v1.5 small patch * title home page * Update content.js * Delete db-test.js * Update content.js * Update home page card * Update v3.7.0 * Update v3.7.1-beta > migrating backend to main code > fixed schedule component * Update v3.8.0 > Added dub options > Moved schedule backend * Update v.3.8.1 > Fixed episodes on watch page isn't dubbed * Update v3.8.1-patch-1 * Update v3.8.1-patch-2 > Another patch for dub * Update v3.8.2 > Removed prisma configuration for database since it's not stable yet * Update v3.8.3 > Fixed different provider have same id * Update v.3.8.3 > Fixed player bug where the controls won't hide after updating anilist progress * Update v3.8.4-patch-2 * Update v3.8.5 > Update readme.md > Update .env.example --- pages/en/anime/[...id].js | 1000 ++++----------------------------------------- 1 file changed, 79 insertions(+), 921 deletions(-) (limited to 'pages/en/anime/[...id].js') diff --git a/pages/en/anime/[...id].js b/pages/en/anime/[...id].js index 86396e3..0b83f24 100644 --- a/pages/en/anime/[...id].js +++ b/pages/en/anime/[...id].js @@ -1,22 +1,8 @@ -import Skeleton from "react-loading-skeleton"; - -import { - ChevronDownIcon, - ClockIcon, - HeartIcon, -} from "@heroicons/react/20/solid"; -import { - TvIcon, - ArrowTrendingUpIcon, - RectangleStackIcon, -} from "@heroicons/react/24/outline"; - import Head from "next/head"; import Image from "next/image"; import { useRouter } from "next/router"; import { useEffect, useState } from "react"; import Layout from "../../../components/layout"; -import Link from "next/link"; import Content from "../../../components/home/content"; import Modal from "../../../components/modal"; @@ -28,252 +14,75 @@ import { GET_MEDIA_USER } from "../../../queries"; import { GET_MEDIA_INFO } from "../../../queries"; import { ToastContainer } from "react-toastify"; -import { convertSecondsToTime } from "../../../utils/getTimes"; - -// import { aniInfo } from "../../components/devComp/data"; -// console.log(GET_MEDIA_USER); -export default function Info({ info, color, api }) { - // Episodes dropdown - const [firstEpisodeIndex, setFirstEpisodeIndex] = useState(0); - const [lastEpisodeIndex, setLastEpisodeIndex] = useState(); - const [selectedRange, setSelectedRange] = useState("All"); - function onEpisodeIndexChange(e) { - if (e.target.value === "All") { - setFirstEpisodeIndex(0); - setLastEpisodeIndex(); - setSelectedRange("All"); - return; - } - setFirstEpisodeIndex(e.target.value.split("-")[0] - 1); - setLastEpisodeIndex(e.target.value.split("-")[1]); - setSelectedRange(e.target.value); - } +import DetailTop from "../../../components/anime/mobile/topSection"; +import DesktopDetails from "../../../components/anime/infoDetails"; +import AnimeEpisode from "../../../components/anime/episode"; +export default function Info({ info, color }) { const { data: session } = useSession(); - const [episode, setEpisode] = useState(null); const [loading, setLoading] = useState(false); const [progress, setProgress] = useState(0); const [statuses, setStatuses] = useState(null); const [domainUrl, setDomainUrl] = useState(""); const [showAll, setShowAll] = useState(false); - const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false); - const [time, setTime] = useState(0); const { id } = useRouter().query; - const [epiView, setEpiView] = useState("3"); - - const [artStorage, setArtStorage] = useState(null); - const rec = info?.recommendations?.nodes?.map( (data) => data.mediaRecommendation ); - const [provider, setProvider] = useState(); - const [prvValue, setPrvValue] = useState("gogoanime"); - - const [availableProviders, setAvailableProviders] = useState([]); - // const [err, setErr] = useState(''); - - function handleProvider(e) { - setEpisode( - Array.isArray(provider[e.target.value]) - ? provider[e.target.value]?.reverse() - : provider[e.target.value] - ); - setPrvValue(e.target.value); - localStorage.setItem("provider", e.target.value); - } - - //for episodes dropdown - useEffect(() => { - setFirstEpisodeIndex(0); - setLastEpisodeIndex(); - setSelectedRange("All"); - }, [info, prvValue]); - useEffect(() => { handleClose(); async function fetchData() { setLoading(true); if (id) { try { - const { protocol, host } = window.location; - const prv = localStorage.getItem("provider"); - const url = `${protocol}//${host}`; - - const view = localStorage.getItem("epiView"); - - if (prv) { - setPrvValue(prv); - } else { - setPrvValue("gogoanime"); - } - - setDomainUrl(url); + setDomainUrl(window.location.origin); - setArtStorage(JSON.parse(localStorage.getItem("artplayer_settings"))); - - setEpisode(null); setProgress(0); setStatuses(null); - let reloadCount = 0; - - try { - const fetchPromises = [ - fetch(`${api}/meta/anilist/info/${info.id}?provider=enime`), - fetch(`${api}/meta/anilist/info/${info.id}?provider=zoro`), - fetch(`${api}/meta/anilist/info/${info.id}?provider=gogoanime`), - ]; - - const results = await Promise.allSettled(fetchPromises); - const successfulResponses = []; - let errorCount = 0; - - results.forEach((result) => { - if (result.status === "fulfilled") { - successfulResponses.push(result.value); - } else { - errorCount++; - } - }); - - if (errorCount === fetchPromises.length) { - // All fetch requests failed, handle the error here - setEpisode([]); - } else { - // Process the successfulResponses here - const responsesData = await Promise.all( - successfulResponses.map((response) => response.json()) - ); - const [enime, zoro, gogoanime] = responsesData; - - const prov = { - enime: enime?.episodes || enime, - zoro: zoro?.episodes || zoro, - gogoanime: gogoanime?.episodes || gogoanime, - }; - - const aPrv = [ - { - name: "enime", - available: - enime?.episodes && enime?.episodes.length > 0 - ? true - : false, + if (session?.user?.name) { + const response = await fetch("https://graphql.anilist.co/", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + query: GET_MEDIA_USER, + variables: { + username: session?.user?.name, }, - { - name: "zoro", - available: - zoro?.episodes && zoro?.episodes.length > 0 ? true : false, - }, - { - name: "gogoanime", - available: - gogoanime?.episodes && gogoanime?.episodes.length > 0 - ? true - : false, - }, - ]; - - setAvailableProviders(aPrv); - - const infProv = { - enime: enime, - zoro: zoro, - gogoanime: gogoanime, - }; - - if (prv) { - setEpisode( - Array.isArray(prov[prv]) ? prov[prv]?.reverse() : prov[prv] - ); - } else { - setEpisode( - Array.isArray(prov["gogoanime"]) - ? prov["gogoanime"]?.reverse() - : prov["gogoanime"] - ); - } - - const data = infProv[prv] || infProv["gogoanime"]; - // const data = aniInfo; - if (!data || data?.episodes?.length === 0) { - setEpisode([]); - } else { - if (data.episodes?.some((i) => i.title === null)) { - setEpiView("3"); - } else if (view) { - setEpiView(view); - } else { - setEpiView("3"); - } - } - - if (session?.user?.name) { - const response = await fetch("https://graphql.anilist.co/", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - query: GET_MEDIA_USER, - variables: { - username: session?.user?.name, - }, - }), - }); - - const responseData = await response.json(); - - const prog = responseData?.data?.MediaListCollection; - - if (prog && prog.lists.length > 0) { - const gut = prog.lists - .flatMap((item) => item.entries) - .find((item) => item.mediaId === parseInt(id[0])); - - if (gut) { - setProgress(gut.progress); - const statusMapping = { - CURRENT: { name: "Watching", value: "CURRENT" }, - PLANNING: { name: "Plan to watch", value: "PLANNING" }, - COMPLETED: { name: "Completed", value: "COMPLETED" }, - DROPPED: { name: "Dropped", value: "DROPPED" }, - PAUSED: { name: "Paused", value: "PAUSED" }, - REPEATING: { name: "Rewatching", value: "REPEATING" }, - }; - setStatuses(statusMapping[gut.status]); - } - } - } + }), + }); - if (data.nextAiringEpisode) { - setTime( - convertSecondsToTime(data.nextAiringEpisode.timeUntilAiring) - ); + const responseData = await response.json(); + + const prog = responseData?.data?.MediaListCollection; + + if (prog && prog.lists.length > 0) { + const gut = prog.lists + .flatMap((item) => item.entries) + .find((item) => item.mediaId === parseInt(id[0])); + + if (gut) { + setProgress(gut.progress); + const statusMapping = { + CURRENT: { name: "Watching", value: "CURRENT" }, + PLANNING: { name: "Plan to watch", value: "PLANNING" }, + COMPLETED: { name: "Completed", value: "COMPLETED" }, + DROPPED: { name: "Dropped", value: "DROPPED" }, + PAUSED: { name: "Paused", value: "PAUSED" }, + REPEATING: { name: "Rewatching", value: "REPEATING" }, + }; + setStatuses(statusMapping[gut.status]); } - - setProvider(prov); - } - } catch (error) { - console.error(error); - if (reloadCount < 2) { - reloadCount++; - setTimeout(() => { - window.location.reload(); - }, 1000); - } else { - setEpisode([]); } } } catch (error) { console.error(error); - setTimeout(() => { - window.location.reload(); - }, 1000); } finally { setLoading(false); } @@ -292,8 +101,6 @@ export default function Info({ info, color, api }) { document.body.style.overflow = "auto"; } - const filterProviders = availableProviders?.filter((x) => x.available); - return ( <> @@ -343,7 +150,7 @@ export default function Info({ info, color, api }) {
{info ? ( - banner anime + <> + banner anime + banner anime + ) : (
)}
- {/* Mobile */} + {/* Mobile Anime Information */} -
-
-

- {info?.title?.romaji || info?.title?.english} -

-

-

- {info?.genres - ?.slice( - 0, - info?.genres?.length > 3 ? info?.genres?.length : 3 - ) - .map((item, index) => ( - - {item} - - ))} -
- {info && ( -
-
- -
- -
-
-
- )} -
-
-
- {info && info.status !== "NOT_YET_RELEASED" ? ( - <> -
- -

{info?.type}

-
-
- -

{info?.averageScore}%

-
-
- - {info?.episodes ? ( -

{info?.episodes} Episodes

- ) : ( -

TBA

- )} -
- - ) : ( -
{info && "Not Yet Released"}
- )} -
-
-
- - {/* PC */} -
-
- {info ? ( - <> -
- poster anime - - - ) : ( - - )} -
+ - {/* PC */} -
-
-

- {info ? ( - info?.title?.romaji || info?.title?.english - ) : ( - - )} -

- {info ? ( -
- {info?.episodes && ( -
- {info?.episodes} Episodes -
- )} - {info?.startDate?.year && ( -
- {info?.startDate?.year} -
- )} - {info?.averageScore && ( -
- {info?.averageScore}% -
- )} - {info?.type && ( -
- {info?.type} -
- )} - {info?.status && ( -
- {info?.status} -
- )} -
- Sub | EN -
-
- ) : ( - - )} -
- {info ? ( -

- ) : ( - - )} -

-
+ {/* PC Anime Information*/} + -
-
- {info?.relations?.edges?.length > 0 && ( -
- Relations -
- )} - {info?.relations?.edges?.length > 3 && ( -
setShowAll(!showAll)} - > - {showAll ? "show less" : "show more"} -
- )} -
-
- {info?.relations?.edges ? ( - info?.relations?.edges - .slice(0, showAll ? info?.relations?.edges.length : 3) - .map((r, index) => { - const rel = r.node; - return ( - -
-
- {rel.id} -
-
-
- {r.relationType} -
-
- {rel.title.userPreferred || rel.title.romaji} -
-
{rel.type}
-
-
- - ); - }) - ) : ( - <> - {[1, 2, 3].map((item) => ( -
- -
- ))} -
- -
- - )} -
-
-
-
-
-
- {info && ( -

- Episodes -

- )} - {info?.nextAiringEpisode && ( -
-
-

Next :

-
- {time} -
-
-
- -
-
- )} -
-
setVisible(!visible)} - > - - - -
-
-
-
- {filterProviders?.length > 0 && ( -
-

Provider

- - -
- )} - {episode?.length > 50 && ( -
-

Episodes

- - -
- )} -
-
-
0 - ? episode?.some((item) => item?.title === null) - ? "pointer-events-none" - : "cursor-pointer" - : "pointer-events-none" - } - onClick={() => { - setEpiView("1"); - localStorage.setItem("epiView", "1"); - }} - > - - 0 - ? episode?.some((item) => item?.title === null) - ? "fill-[#1c1c22]" - : epiView === "1" - ? "fill-action" - : "fill-[#3A3A44]" - : "fill-[#1c1c22]" - }`} - rx="3" - > - -
-
0 - ? episode?.some((item) => item?.title === null) - ? "pointer-events-none" - : "cursor-pointer" - : "pointer-events-none" - } - onClick={() => { - setEpiView("2"); - localStorage.setItem("epiView", "2"); - }} - > - 0 - ? episode?.some((item) => item?.title === null) - ? "fill-[#1c1c22]" - : epiView === "2" - ? "fill-action" - : "fill-[#3A3A44]" - : "fill-[#1c1c22]" - }`} - viewBox="0 0 33 20" - > - - - -
-
0 - ? `cursor-pointer` - : "pointer-events-none" - } - onClick={() => { - setEpiView("3"); - localStorage.setItem("epiView", "3"); - }} - > - 0 - ? epiView === "3" - ? "fill-action" - : "fill-[#3A3A44]" - : "fill-[#1c1c22]" - }`} - viewBox="0 0 33 20" - > - - - - -
-
-
-
- {!loading ? ( - Array.isArray(episode) ? ( - episode && ( -
- {episode?.length !== 0 && episode ? ( -
- {epiView === "1" - ? episode - .slice(firstEpisodeIndex, lastEpisodeIndex) - ?.map((epi, index) => { - const time = artStorage?.[epi?.id]?.time; - const duration = - artStorage?.[epi?.id]?.duration; - let prog = (time / duration) * 100; - if (prog > 90) prog = 100; - return ( - - - Episode {epi?.number} - - -
- epi image - - ); - }) - : ""} - {epiView === "2" && - episode - .slice(firstEpisodeIndex, lastEpisodeIndex) - .map((epi, index) => { - const time = artStorage?.[epi?.id]?.time; - const duration = - artStorage?.[epi?.id]?.duration; - let prog = (time / duration) * 100; - if (prog > 90) prog = 100; - return ( - -
-
- Anime Cover - - - Episode {epi?.number} - -
- - - -
-
-
+ {/* Episodes */} -
-

- {epi?.title} -

- {epi?.description && ( -

- {epi?.description} -

- )} -
- - ); - })} - {epiView === "3" && - episode - .slice(firstEpisodeIndex, lastEpisodeIndex) - .map((epi, index) => { - return ( -
- -

Episode {epi.number}

- {epi.title && ( -

- "{epi.title}" -

- )} - - {index !== episode?.length - 1 && ( - - )} -
- ); - })} -
- ) : ( -

No Episodes Available

- )} -
- ) - ) : ( -
-
-                      {episode?.message}
-                    
-
- ) - ) : ( -
-
-
-
-
-
-
-
- )} -
+
{info && rec?.length !== 0 && (
@@ -1114,17 +286,3 @@ function setTxtColor(hexColor) { const brightness = getBrightness(hexColor); return brightness < 150 ? "#fff" : "#000"; } - -const getLanguageClassName = (language) => { - switch (language) { - case "javascript": - return "language-javascript"; - case "html": - return "language-html"; - case "bash": - return "language-bash"; - // add more languages here as needed - default: - return ""; - } -}; -- cgit v1.2.3